import os
from PIL import Image
import imagehash
import tkinter as tk
from tkinter import filedialog, messagebox


def get_image_hashes(folder_path):
    """
    计算指定文件夹中所有图片的哈希值
    :param folder_path: 文件夹路径
    :return: 图片路径和哈希值的字典
    """
    image_hashes = {}
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith(('.png', '.jpg', '.jpeg')):
                file_path = os.path.join(root, file)
                try:
                    with Image.open(file_path) as img:
                        hash_value = imagehash.average_hash(img)
                        image_hashes[file_path] = hash_value
                except Exception as e:
                    print(f"Error processing {file_path}: {e}")
    return image_hashes


def find_similar_images(image_hashes, threshold=3):
    """
    找出相似的图片
    :param image_hashes: 图片路径和哈希值的字典
    :param threshold: 哈希值差异阈值，越小表示越相似
    :return: 相似图片的列表
    """
    similar_images = []
    image_paths = list(image_hashes.keys())
    for i in range(len(image_paths)):
        for j in range(i + 1, len(image_paths)):
            hash1 = image_hashes[image_paths[i]]
            hash2 = image_hashes[image_paths[j]]
            if hash1 - hash2 <= threshold:
                similar_images.append((image_paths[i], image_paths[j]))
    return similar_images


def delete_similar_images(similar_images):
    """
    删除相似的图片
    :param similar_images: 相似图片的列表
    """
    deleted_images = set()
    for img1, img2 in similar_images:
        if img1 not in deleted_images and img2 not in deleted_images:
            try:
                os.remove(img2)
                deleted_images.add(img2)
                print(f"Deleted: {img2}")
            except Exception as e:
                print(f"Error deleting {img2}: {e}")


def select_folder():
    folder_path = filedialog.askdirectory()
    if folder_path:
        folder_entry.delete(0, tk.END)
        folder_entry.insert(0, folder_path)


def start_processing():
    folder_path = folder_entry.get()
    if not os.path.exists(folder_path):
        messagebox.showerror("错误", "输入的文件夹路径不存在，请检查后重新输入。")
        return
    try:
        # 计算图片的哈希值
        image_hashes = get_image_hashes(folder_path)
        # 找出相似的图片
        similar_images = find_similar_images(image_hashes)
        # 删除相似的图片
        delete_similar_images(similar_images)
        messagebox.showinfo("完成", "相似图片删除完成。")
    except Exception as e:
        messagebox.showerror("错误", f"处理过程中出现错误: {str(e)}")


# 创建主窗口
root = tk.Tk()
root.title("相似图片删除工具")

# 创建文件夹选择部分
folder_label = tk.Label(root, text="选择文件夹:")
folder_label.pack(pady=10)

folder_entry = tk.Entry(root, width=50)
folder_entry.pack(pady=5)

select_button = tk.Button(root, text="选择文件夹", command=select_folder)
select_button.pack(pady=10)

# 创建开始处理按钮
start_button = tk.Button(root, text="开始处理", command=start_processing)
start_button.pack(pady=20)

# 运行主循环
root.mainloop()